package cn.xshi.job.publisher;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import cn.xshi.common.util.JsonUtil;
import cn.xshi.job.vo.ChannelEntity;
import cn.xshi.job.vo.RequestInfo;
import lombok.extern.slf4j.Slf4j;
/**
 * 服务端处理器
 */
@Slf4j
public class NettyServerHandler extends ChannelInboundHandlerAdapter{

    ChannelUtil channelUtil;

    public NettyServerHandler(){

    }

    public NettyServerHandler(ChannelUtil channelUtil){
        this.channelUtil = channelUtil;
    }

    /**
     * 客户端连接会触发
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("Channel active......");
    }

    /**
     * 客户端发消息会触发
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        log.info("Received message from server : {}", msg.toString());
        RequestInfo requestInfo = JsonUtil.fromAliFastJson(msg.toString(), RequestInfo.class);
        if(requestInfo.isShakeHands()){//初次握手
            this.channelUtil.add(ctx.channel());
            ChannelEntity channelEntity = new ChannelEntity(ctx.channel(),requestInfo.getClientGroupId(),requestInfo.getClientId(),requestInfo);
            boolean res1 = this.channelUtil.putChannel(ctx.channel().id().asLongText(),channelEntity);
            if(res1){
                log.info("Channel"+ctx.channel().id().asLongText()+"加入到缓存中成功......");
            }else{
                log.info("Channel"+ctx.channel().id().asLongText()+"加入到缓存中失败......");
            }

            boolean res = this.channelUtil.put(requestInfo.getClientGroupId(),channelEntity);
            if(res){
                log.info("通道号"+ctx.channel().id().asLongText()+"加入到缓存中成功......");
            }else{
                log.info("通道号"+ctx.channel().id().asLongText()+"加入到缓存中失败......");
            }

            /*
            ////////测试用例////////
            while (true){
                NettyUtil nettyUtil = new NettyUtil();
                RequestInfo info = new RequestInfo();
                info.setMessage("发送一下...");
                JobHandlerEntity jobHandlerEntity = new JobHandlerEntity("testJobHandler");
                info.setJobHandlerEntity(jobHandlerEntity);
                channelEntity.setRequestInfo(info);
                nettyUtil.sendMessage(channelEntity);
                try {
                    Thread.sleep(20000);
                }catch (Exception e){

                }
            }
            */
        }
        ctx.write(msg.toString());//握手反馈
        ctx.flush();
    }

    /**
     * 发生异常触发
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    /**
     * 客户端连接之后获取客户端channel并放入group中管理
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        super.handlerAdded(ctx);
        Channel channel = ctx.channel();
        log.info("有通道号连接进来......"+channel.id().asLongText());
    }

    /**
     * 移除对应客户端的channel
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        super.handlerRemoved(ctx);
        log.info("通道号"+ctx.channel().id().asLongText()+"离线......");
        Channel channel = ctx.channel();
        boolean res = this.channelUtil.delete(channel);
        if(res){
            log.info("从通道组中移除通道号："+channel.id().asLongText()+"成功！");
            ChannelEntity channelEntity = this.channelUtil.getChannel(channel.id().asLongText());
            //移除
            res = this.channelUtil.removeChannel(channel.id().asLongText());
            if(res){
                log.info("从Channel缓存中移除通道号："+channel.id().asLongText()+"成功！");
            }else{
                log.info("从Channel缓存中移除通道号："+channel.id().asLongText()+"失败！");
            }
            if(null != channelEntity){
                res = this.channelUtil.remove(channelEntity.getClientGroupId(),channelEntity.getClientId());
            }
            if(res){
                log.info("从缓存中移除通道号："+channel.id().asLongText()+"成功！");
            }else{
                log.info("从缓存中移除通道号："+channel.id().asLongText()+"失败！");
            }
        }else{
            log.info("从通道组中移除通道号："+channel.id().asLongText()+"失败！");
        }
    }
}
